﻿using UnityEngine;

//拖到摄影机
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class CameraSurround : MonoBehaviour
{
    public enum DragMouse { MouesLeft, MouseRight }

    public static CameraSurround instance;

    public DragMouse dragMouse = DragMouse.MouesLeft;
    public Transform target;
    public Vector3 viewPointOffset;
    public float angleHorizontal;
    public float angleVertical;
    public float angleVerticalMin = -89;
    public float angleVerticalMax = 89;
    public bool canRotate = true;
    public float distance = 2;
    public float distanceMin = 0.1f;
    public float distanceMax = 10;
    public float autoRotateSpeed = 0;
    public bool canWheel = true;
    public float dragSpeed = 200;
    public float wheelSpeed = 1;

    Camera _camera;
    Vector2 previousPos, dragDelta;
    bool canDrag;

    private void Awake()
    {
        instance = this;
        _camera = GetComponent<Camera>();
    }

    public void Cancel()
    {
        canDrag = false;
    }

    private void LateUpdate()
    {
        if (!target) return;

        int mouseIndex = dragMouse == DragMouse.MouesLeft ? 0 : 1;
        if (canRotate)
        {
            if (Input.GetMouseButtonDown(mouseIndex) && !IsTouchOnUI())
            {
                previousPos = _camera.ScreenToViewportPoint(Input.mousePosition);
                canDrag = true;
            }

            if (canDrag)
            {
                Vector2 newPos = _camera.ScreenToViewportPoint(Input.mousePosition);
                dragDelta = (newPos - previousPos) * dragSpeed;
                previousPos = newPos;
                angleHorizontal -= dragDelta.x;
                angleVertical -= dragDelta.y;
                if (angleVertical < angleVerticalMin)
                {
                    angleVertical = angleVerticalMin;
                }
                if (angleVertical > angleVerticalMax)
                {
                    angleVertical = angleVerticalMax;
                }
            }
            else
            {
                if (autoRotateSpeed != 0)
                {
                    angleHorizontal -= autoRotateSpeed * Time.deltaTime;
                }
            }
        }

        Vector3 viewPos = target.position + viewPointOffset;
        Vector3 pos = viewPos;
        float radian = angleHorizontal * Mathf.Deg2Rad;
        pos.x += Mathf.Cos(radian) * distance;
        pos.z += Mathf.Sin(radian) * distance;
        transform.position = pos;
        Vector2 vetor = new Vector2(transform.position.x - viewPos.x, transform.position.z - viewPos.z);
        Vector2 vetor2 = Vector2.Perpendicular(vetor);
        Vector3 axis = new Vector3(vetor2.x, 0, vetor2.y);
        transform.RotateAround(viewPos, axis, angleVertical);
        transform.LookAt(viewPos);

        if (Input.GetMouseButtonUp(mouseIndex))
        {
            canDrag = false;
        }

        if (!Application.isMobilePlatform)
        {
            if (canWheel && !IsTouchOnUI())
            {
                float scroll = Input.GetAxis("Mouse ScrollWheel");
                distance -= scroll * wheelSpeed;
                if (distance < distanceMin)
                {
                    distance = distanceMin;
                }
                if (distance > distanceMax)
                {
                    distance = distanceMax;
                }
            }
        }
    }

    private bool IsTouchOnUI(int fingerId = 0)
    {
        if (UnityEngine.EventSystems.EventSystem.current)
        {
            if (Application.isMobilePlatform)
            {
                return UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject(fingerId);
            }
            else
            {
                return UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject();
            }
        }
        return false;
    }
}
